package com.java.comprehensive.design.open;

import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import java.io.IOException;
import java.util.Locale;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ExtractorReport_OpenClosePrinciple {
    public static void main(String[] args) throws IOException {
        new NumberExtractorReport().prepareAndSendReport("data.txt");
        new EmailExtractorReport().prepareAndSendReport("data.txt");
    }
}

abstract class ExtractorReport {
    public abstract Pattern getPattern();

    public abstract String getReportName();

    public abstract String clean(String input);

    private String parse(String path) throws IOException {

        StringBuilder out = new StringBuilder();
//        File file = new File(path);
//        File file = ResourceUtils.getFile("classpath:" + path);
        Resource resource = new ClassPathResource(path);
        Scanner scanner = new Scanner(resource.getFile());
        if (scanner.hasNext()) {
            scanner.nextLine();
        } else {
            return "empty file";
        }
        while (scanner.hasNext()) {
            String nextLine = scanner.nextLine();

            Matcher matcher = getPattern().matcher(nextLine);

            boolean matches = matcher.matches();
            if (matches) {
                out.append(clean(nextLine)).append("\n");
            }
        }
        return StringUtils.isNotBlank(out.toString()) ? out.toString() : "empty file";
    }

    public void prepareAndSendReport(String path) throws IOException {
        System.out.println("starting report" + getReportName() + "...");
        String report = parse(path);
        System.out.println(report);
        System.out.println("send report" + getReportName() + "...");
    }
}

class NumberExtractorReport extends ExtractorReport {
    private static final Pattern PATTERN = Pattern.compile("^[0-9]*$");

    @Override
    public Pattern getPattern() {
        return PATTERN;
    }

    @Override
    public String getReportName() {
        return "Phone Numbers";
    }

    @Override
    public String clean(String input) {
        return input;
    }
}

class EmailExtractorReport extends ExtractorReport {
    private static final Pattern PATTERN = Pattern.compile("^\\w+@[a-z0-9]+\\.[a-z]{2,4}$");

    @Override
    public Pattern getPattern() {
        return PATTERN;
    }

    @Override
    public String getReportName() {
        return "Emails";
    }

    @Override
    public String clean(String input) {
        return input.toUpperCase(Locale.ROOT);
    }
}
